package com.example.wan1.base.injection;

import com.example.wan1.base.mvp.BasePresenter;
import com.example.wan1.base.mvp.IBaseView;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/***
 * 应该是反射接口的实现类
 *
 * 注意：这里没必要去反射，也不能用反射。给DataClient赋值，因为在BasePresenter中attachview的时候就可以赋值.
 * 引出另外一个问题：什么时候执行DataClient实例化最好呢？在绑定view的时候还是当子类继承真正去用的时候呢
 * 因为在loginPresenter中使用，觉得都还可以。
 *
 * 注意：这里的mInjectPresenters有可能是空的，但是mProxyFragment是不为空的，这个仅仅在项目界面出现了这个问题。待观察！
 * 而且这里的mInjectPresenters，保存每次的p和v的关系，所以这里的实例化，能不能放到bindPresenter方法中进行，就不再构造方法中实例化了
 */
public class ProxyImpl implements IProxy {

    private IBaseView mView;
    private List<BasePresenter> mInjectPresenters;

    public ProxyImpl(IBaseView view) {
        this.mView = view;
        mInjectPresenters = new ArrayList<>();
    }

    @SuppressWarnings({"unchecked", "TryWithIdenticalCatches"})
    @Override
    public void bindPresenter() {
        Field[] fields = mView.getClass().getDeclaredFields();
        for (Field field : fields) {
            InjectPresenter injectPresenter = field.getAnnotation(InjectPresenter.class);
            if (injectPresenter != null) {
                try {
                    Class<? extends BasePresenter> type = (Class<? extends BasePresenter>) field.getType();

                    BasePresenter mInjectPresenter = type.newInstance();//无参数的时候可以这么弄
                    mInjectPresenter.attachView(mView);
                    field.setAccessible(true);//暴力反射
                    field.set(mView, mInjectPresenter);
                    if (mInjectPresenters == null) mInjectPresenters = new ArrayList<>();
                    mInjectPresenters.add(mInjectPresenter);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (ClassCastException e) {
                    e.printStackTrace();
                    throw new RuntimeException("SubClass must extends Class:BasePresenter");
                }
            }
        }
    }

    @Override
    public void unBindPresenter() {
        if (mInjectPresenters == null) return;
        for (BasePresenter presenter : mInjectPresenters) {
            presenter.detachView();
        }
        mInjectPresenters.clear();
        mInjectPresenters = null;
    }

}
